function [results1, results0] = analyCascading(ImgSetList, Net, solver_mode, bForceUpdate, PSNR_SSIM_Figures, bPlotStartingPSNR)

%%
if nargin == 0
    solver_mode = 'gpu 1';
    ImgSetList = 'Set5';
    PSNR_SSIM_Figures = true;
    bPlotStartingPSNR = true;
    Net = {
        'startingNet', 'Bicubic'
        'scale',        3
        'path',         'VDSR-y-noskip-Scale(3)/VDSR_y_noskip1'
        'deploy_file',	'VDSR_y_noskip_deploy'
        'alias_names',	'VDSR_NoSkip_Bicubic_MSRA'
        'model_folders'  'models'
        'model_iters',	 '[110000 Inf]'
        'model_prefix',  'VDSR_y_noskip_iter_'
        };
end
if nargin < 4, bForceUpdate = false; end
if nargin < 5, PSNR_SSIM_Figures = []; end
if nargin < 6, bPlotStartingPSNR = true; end

%%
if ischar(ImgSetList), ImgSetList = {ImgSetList}; end

MatFile = sranaly.getOutputFile(Net);
load(MatFile);  bFoundResults = exist('results1', 'var');

bSetNetPath = true;
Net = srmodel.parseNetParam(Net); Net0 = Net;

%%
% close all
if bForceUpdate, pre_results1 = []; end

for si = 1 : length(ImgSetList)
    ImgSet = ImgSetList{si};
    
    %%
    if bSetNetPath && isunix
        bSetNetPath = false;
        Net = srmodel.setNetPath(Net);
        Net0 = Net;
    end
    Net = Net0;
    
    %%
    bFoundCurSet = bFoundResults && isfield(results1, ImgSet);
    CheckList = false(1, length(Net.model_folders));
    if ~bFoundCurSet
        results1.(ImgSet) = cell(length(Net.model_folders), 4);
    elseif ~bForceUpdate
        [CheckList, results1, Net] = getCheckList(Net, results1, ImgSet, MatFile);
        if all(CheckList)
            continue
        end
    end
    
    %% Starting Net
    fprintf('Super-Resolve Image Set "%s" by Starting Net "%s" on Scale %d ...\n', ImgSet, Net.startingNet, Net.scale);
    [psnrs, ssims, Y, Yhat] = sranaly.analySRQuality(ImgSet, [], Net.scale, Net.startingNet, [], solver_mode);
    results0.(ImgSet) = {mean(psnrs), mean(ssims)};
    if bFoundResults
        save(MatFile, 'results0', '-append');
    else
        save(MatFile, 'results0');
    end
    
    %% Fine Tuning
    for i = 1 : length(Net.model_folders)
        fprintf('Refine Image Set "%s" by Net "%s" on Scale %d ...\n', ImgSet, Net.alias_names{i}, Net.scale);
        
        Net.model_path = Net.model_folders{i};
        if CheckList(i), continue; end
        try
            if ~bForceUpdate
                pre_results1 = results1.(ImgSet)(i, :);
            end
            [results1.(ImgSet){i, :}] = sranaly.analyIterModels(Yhat, Y, Net.scale, Net, Net.model_iters{i}, solver_mode, pre_results1);
            save(MatFile, 'results1', '-append');
        catch ME
            if strcmp(ME.identifier, 'getModelFiles:EmptyModels')
                continue
            end
            rethrow(ME);
        end
    end
end

%%
% sranaly.printMaxPSNR(Net.startingNet, results0);
disp(results0)
sranaly.printMaxPSNR(Net.alias_names, results1);

if isempty(PSNR_SSIM_Figures), return; end
for si = 1 : length(ImgSetList)
    ImgSet = ImgSetList{si};
    results = results1.(ImgSet);
    srmodel.plotIterPSNR(results0.(ImgSet){:}, Net.alias_names, results(:, 1), results(:, 2), results(:, 3), results(:, 4), bPlotStartingPSNR, PSNR_SSIM_Figures);
end

%%
% model_files = mycaffe.getModelFiles(mynet.model_path, Net.model_prefix, ModelIters);
% caffemodel = fullfile(mynet.model_path, model_files{end});
% hDeploy = @(x) mycaffe.caffe(x, Net.deploy_file, caffemodel, 'test');

% srmodel.showSRImages(ImgSet, Net.scale, mynet.name, hDeploy);

function [CheckList, results1, Net] = getCheckList(Net, results1, ImgSet, MatFile)
CheckList = cellfun(@(x)~isempty(x), results1.(ImgSet)(:, 1), 'UniformOutput', false);
CheckList = [CheckList{:}];

bBigSet = srdata.isBigDataSet(ImgSet);
if bBigSet
    BestModelItersList = sranaly.getBestModelIters(results1);
end

for i = 1 : length(Net.model_folders)
    Net.model_path = Net.model_folders{i};
    if ~isunix, continue; end
    
    if ~CheckList(i)
        if bBigSet
            Net.model_iters{i} = BestModelItersList{i};
        end
        continue
    end
    
    ModelIters_old = results1.(ImgSet){i, end};
    
    %% merge repeated psnr and ssim results
    if bBigSet
        len = length(ModelIters_old);
        [ModelIters_old, idx] = unique(ModelIters_old);
        if length(ModelIters_old) < len
            results1.(ImgSet){i, end} = ModelIters_old;
            results1.(ImgSet){i, 1} = results1.(ImgSet){i, 1}(:, idx);
            results1.(ImgSet){i, 2} = results1.(ImgSet){i, 2}(:, idx);
            save(MatFile, 'results1', '-append');
        end
    end
    
    %% compare the old saved iters with the new iters
    if bBigSet
        ModelIters_new = BestModelItersList{i};
    else
        [ModelFiles, ModelIters_new] = mycaffe.getModelFiles(Net.model_path, Net.model_prefix, Net.model_iters{i});
    end
    
    [ModelIters, Idx] = setdiff(ModelIters_new, ModelIters_old);
    if isempty(ModelIters), continue; end
    CheckList(i) = false;
    
    if bBigSet
        Net.model_iters{i} = ModelIters;
    else
        Net.model_iters{i} = {ModelFiles(Idx) ModelIters};
    end
end
